﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using PropertyExpression.Common;

namespace PropertyExpression.ControllableQuery.Test2
{
    static class Program
    {
        static void Main()
        {
            Test001(new DateTime(2000, 1, 1));
            Test002();
            Test003(new DateTime(2000, 1, 1));
            Test004();
        }

        private static void Test004()
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    new {}.Apply(p => {
                        return new Type<Non>();
                    });
                }
            }
        }

        private static void Test003(DateTime? date)
        {
            var record = new {date}.Apply((p, c) => {
                var builder = new StringBuilder(@"
SELECT  TOP 1
        Id, CreationDate
FROM    Post
WHERE   1 = 1");
                if (p.date.HasValue)
                {
                    builder.Append(@"
        AND CreationDate >= @Date");
                    c.AddParameter("@Date", p.date);
                }
                c.CommandText = builder.ToString();
                return new Type<T001>();
            }).GetEnumerable().First();
            Console.WriteLine("{0}, {1}", record.Id, record.CreationDate);
        }

        private static IEnumerable<T> GetEnumerable<T>(this Func<SqlCommand, Type<T>> func)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    var type = func(command);
                    using (var reader = command.ExecuteReader())
                        while (reader.Read())
                            yield return reader.Materialize(type);
                }
            }
        }

        private static void Test002()
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    var type = new {command}.Apply(p => {
                        p.command.CommandText = @"
SELECT  TOP 1
        Id, CreationDate
FROM    Post;

SELECT  TOP 1
        CreationDate
FROM    Post;";
                        return new Type<Tuple<T001, T002>>();
                    });
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var record = reader.Materialize(type.Type(_ => _.Item1));
                            Console.WriteLine("{0}, {1}", record.Id, record.CreationDate);
                        }
                        reader.NextResult();
                        while (reader.Read())
                            Console.WriteLine(reader.Materialize(type.Type(_ => _.Item2)).CreationDate);
                    }
                }
            }
        }

        private static void Test001(DateTime? date)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    var type = new {date, command}.Apply(p => {
                        var builder = new StringBuilder(@"
SELECT  TOP 1
        Id, CreationDate
FROM    Post
WHERE   1 = 1");
                        if (p.date.HasValue)
                        {
                            builder.Append(@"
        AND CreationDate >= @Date");
                            p.command.AddParameter("@Date", p.date);
                        }
                        p.command.CommandText = builder.ToString();
                        return new Type<T001>();
                    });
                    using (var reader = command.ExecuteReader())
                        while (reader.Read())
                        {
                            var record = reader.Materialize(type);
                            Console.WriteLine("{0}, {1}", record.Id, record.CreationDate);
                        }
                }
            }
        }

        public static string ConnectionString
        {
            get { return @"Data Source=(local)\SQL2012;Initial Catalog=Serverfault;Integrated Security=True"; }
        }
    }
}
